package com.ptc.core.adapter.server.impl;

import wt.adapter.*;
import com.infoengine.object.factory.*;
import com.infoengine.object.*;
import java.io.*;
import wt.adapter.BasicWebjectDelegate;
import wt.fc.*;
import wt.util.*;
import wt.content.*;
import java.net.*;
import com.infoengine.util.Base64;
import wt.pom.*;

public class AddUrlContent extends AbstractWebjectDelegate {

	public static final boolean VERBOSE=false;
	public static final long serialVersionUID = 0;
	private String CONTENTTYPE="";

    public Task invoke(Task task) throws WTException {
		Webject webject = task.getWebject();

        // Processing Variables
			String obid = "";
			String viewurl = "";
			String size="";
			String format="";

/* GET INPUTS */

		// Get the REQUIRED attributes

		String objectRef = webject.paramValue("OBJECT_REF");
		String category  = webject.paramValue("CATEGORY");
		String fileName  = webject.paramValue("FILENAME");
		if(VERBOSE) System.out.println("OBJECT_REF to Attach to: " + objectRef);
		String urlstr= webject.paramValue("URL");
		if(VERBOSE) System.out.println("Open URL: " + urlstr);
		String groupOut = webject.paramValue("GROUP_OUT");
		if(VERBOSE) System.out.println("Output Group Name: " + groupOut);
		String role= webject.paramValue("ROLE",null);
		if(VERBOSE)System.out.println("Role: " + role);
		String isPrimary= "false";
		if ( webject.paramValue("ISPRIMARY") != null ) isPrimary=webject.paramValue("ISPRIMARY");
		else if(role.equalsIgnoreCase("PRIMARY")) isPrimary="true";

		// Other Optional Variables (more are used in TRY and other static methods)
		boolean stagingOnly=(webject.paramValue("STAGING_AREA",null)==null?false:true);

		//setup output group
		Group outputGroup = new Group();
		outputGroup.setName(groupOut);
		outputGroup.setClassName(webject.getClassName());
		Element row = new Element();
		String name= getFileName(webject);
		if(VERBOSE)System.out.println("Filename: " + name);


/* DO THE WORK */

		if (urlstr !=null && objectRef !=null && groupOut !=null && !stagingOnly){

			/* Create content (Doing the Work HERE) */
			Transaction transaction = new Transaction();
		  try{

			// Get Content via URL and store as content inside windchill
				Persistable holder2 = BasicWebjectDelegate.getObjectByUfid(objectRef);
				if (VERBOSE) System.out.println("holder type: " + holder2.getClass().getName());
				if (holder2 instanceof ContentHolder) {
					if(VERBOSE) System.out.println("is instance of contentHolder:  "+holder2);
					ContentHolder holder = (wt.content.ContentHolder) holder2;
					InputStream is=getInputStream(webject);
					ApplicationData contentitem =ApplicationData.newApplicationData(holder);

					contentitem.setUploadedFromPath(null);
					contentitem.setCategory(category);
					contentitem.setFileName(fileName);

					// Set Format Type (optional in webject)
					format = webject.paramValue("FORMAT",CONTENTTYPE);
					contentitem.setFormat(DataFormatReference.newDataFormatReference(format));

					// Check if this should be the PrimaryContent
					if (isPrimary.equalsIgnoreCase("true")) contentitem.setRole(ContentRoleType.PRIMARY);
					else if (role!=null && role.equalsIgnoreCase("SECONDARY")) {}
					else if(role!=null) contentitem.setRole(ContentRoleType.toContentRoleType(role));
					if(VERBOSE) System.out.println("WT Properties set, Start Transaction");

					//add Content to Windchill
					transaction.start();
					PersistenceServerHelper.manager.lock(holder);
					if (isPrimary.equalsIgnoreCase("true")) {
					   holder = ContentServerHelper.service.updateHolderFormat((FormatContentHolder)holder);
					   ContentItem contentOld = ContentHelper.getPrimary((FormatContentHolder)holder);
					   if(contentOld != null)
						 ContentServerHelper.service.deleteContent(holder, contentOld);
					}
					ContentServerHelper.service.updateContent(holder, contentitem, is);
					transaction.commit();
					transaction = null;
					is.close();

					if(VERBOSE) System.out.println("Content Uploaded, get Information");
					viewurl = contentitem.getViewContentURL(holder).toString();


				 // Get Minimum Attributes about Object
					name = contentitem.getFileName();
					obid = BasicWebjectDelegate.getUfid(contentitem);
					if(VERBOSE) System.out.println("Content Uploaded Successfully under category: " + category);
					if(VERBOSE) System.out.println("Content Size of Uploaded file is:  "+contentitem.getFileSize());
					if(VERBOSE) System.out.println("View URL is:  "+viewurl);
					if(VERBOSE) System.out.println("OBID of content = " + obid );
					row.addAtt(new Att("obid", obid) );
					row.addAtt(new Att("size", size) );
					row.addAtt(new Att("format", format) );
					row.addAtt(new Att("viewUrl", viewurl) );
				}
                else{
                	System.out.println("ERROR NOT instance of contentHolder");
                	throw new WTException("Invalid Object, it is not an instance of contentHolder");
                }

			}
			catch(Throwable ex){
				ex.printStackTrace();
				throw new WTException (ex);
			}
			finally {
			    if(transaction != null) {
					transaction.rollback();
					System.out.println("Transaction Rolled Back");
					throw new WTException ("Unable to Complete Transaction, Rollback Successful");
				}
        	}
	    }
	    else if(stagingOnly) {
			try {
				AddContentItemsWebjectDelegate aciwd=new AddContentItemsWebjectDelegate();
				String filedir=aciwd.getStagingAreaPath(webject);
				File output=writeToFile(getInputStream(webject),name,filedir);
				row.addAtt(new Att("directory", filedir) );
				row.addAtt(new Att("fullPath", output.getPath()) );
				row.addAtt(new Att("fileName", output.getName()) );
				row.addAtt(new Att("size", ""+output.length()) );
			}
			catch (Throwable throwable) {
				throw new WTException(throwable);
			}



		}
	    else {
			if ( urlstr == null )
			   throw new WebjectServiceException("URL is a required parameter.");
			if ( objectRef == null )
			   throw new WebjectServiceException("OBJECTREF is a required parameter.");
			if ( groupOut == null )
				throw new WebjectServiceException("GROUP_OUT is required to name the output group.");
			throw new WebjectServiceException("Invalid parameters, check documentation");
		}


/* OUTPUT HERE */
		row.addAtt(new Att("name", name) );
		outputGroup.addElement(row);
		Task outputTask = new Task();
		outputTask.addVdb(outputGroup);
	    return outputTask;
	}




   /*  For Retrieving Source Object */

	private static String getFileName(Webject webject) throws WTException {
		String name= webject.paramValue("NAME",null);
		if(name ==null){
			String urlstr= webject.paramValue("URL",null);
			try {
				URL url = new URL(urlstr);
				name = url.getFile();
			}
			catch (IOException ioex) {
				ioex.printStackTrace();
				throw new WTException(ioex);
			}
			if (name.lastIndexOf("/") >=0) {
				if (name.length() == name.lastIndexOf("/")+1) name=null;
				else name=name.substring(name.lastIndexOf("/")+1);
			}
			if(name.indexOf("?") >0) name=name.substring(0,name.indexOf("?"));
		}
		if (name ==null) name="UNKNOWN";
		return name;
	}

	private InputStream getInputStream(Webject webject) throws WTException{
		InputStream is=null;
		try {
			String urlstr= webject.paramValue("URL",null);
			String dbuser= webject.paramValue("URLDBUSER",null);
			String passwd= webject.paramValue("URLPASSWD",null);
			URL url = new URL(urlstr);
			if(VERBOSE)System.out.println("Opening Connection: " + urlstr);
			URLConnection urlconnection = url.openConnection();
			if(dbuser != null && passwd != null)
				urlconnection.setRequestProperty("Authorization", "Basic " + Base64.encode(dbuser + ':' + passwd));
			else if(webject.paramValue("URLAUTHORIZATION",null) !=null) urlconnection.setRequestProperty("Authorization",  webject.paramValue("URLAUTHORIZATION",""));
			//else System.out.println("anonymous");
			is = urlconnection.getInputStream();
			if(VERBOSE)System.out.println("Got Data from: " + urlstr);
			CONTENTTYPE=urlconnection.getContentType();
		}
		catch(java.net.MalformedURLException ur){
			ur.printStackTrace();
			throw new WTException("Malformed URL ERROR: " + ur.getLocalizedMessage());
		}
		catch(java.io.IOException io){
			io.printStackTrace();
			throw new WTException("IO ERROR: " + io.getLocalizedMessage());
		}
		return is;
	}

	private static File writeToFile(InputStream is, String name,String filedir) throws Exception {
		File file = new File(filedir);
		if(!file.exists() || !file.isDirectory()) {
			if(VERBOSE) System.out.println("Directory not found, Try to make Directory:  "+filedir);
			file.mkdirs();
		}
		String filename=filedir+File.separator+name;
		IeMultipartInputStream iemultipartinputstream = new IeMultipartInputStream(is,"Blob-Results","file","file");
		FileOutputStream fileoutputstream = new FileOutputStream(filename);
		if(VERBOSE) System.out.println("start writing file to: "+filename);
		iemultipartinputstream.readBlob(fileoutputstream);
		if(VERBOSE) System.out.println("Successfully wrote file:  "+filename);
		iemultipartinputstream.close();
		fileoutputstream.close();
		return new File(filename);
	}
}






